<?php
	
	class PDataBase extends PDataContainer
	{
		
		var $connection;
		
		
		function PDatabase($puzzle)
		{
			parent::__construct($puzzle);
			$this->puzzle = $puzzle;
		}
		
		
		function connect($name, $host, $dbname, $user, $pass)
		{
			$connection = new PDatabaseConnection($name, $host, $dbname, $user, $pass);
			$this->connection = $connection;
			$c = $this->connection->connect();
			
			if (!$c)
			{
				die("Puzzle :: Connnecting to database $dbname at $host with user $user :: Error connecting");
			}
			
			return $connection;
		}
		
		function loadEntity($id, $entity_name, $entity_extension = null, $connection = null)
		{
			if ($connection == null)
			{
				$connection = $this->connection;
			}
			
			if ($entity_extension == null)
			{
				$entity_extension = $this->puzzle->PEM->current_extension;
			}
			
			$obj = $this->puzzle->PDM->createModel($entity_name, $entity_extension);
			$obj->defineContainer("mysql");
			
			if ($connection->select($obj->_mysql->table, '*', $obj->_mysql->key . " = " . $id))
			{
				if ($connection->result == null or count($connection->result) == 0)
				{
					return null;
				}
				else
				{
					$rfields = $connection->result[0];
					
					for($i = 0; $i < count($obj->_model->fields); $i++)
					{
						
						$field_name = $obj->_model->fields[$i];
						$field_mapping = $obj->_mysql->mapping[$field_name];
						
						if ($field_mapping == null or $field_mapping == "")
						{
							// If the object has the "Load Not Mapped Fields" as true...
							if ($obj->_mysql->lnmf)
							{
								$field_mapping = $field_name;
							}
						}
						
						if ($field_mapping != null && $field_mapping != "")
						{
							$obj->$field_name = $rfields[$field_mapping];
						}
					}
					
					return $obj;
				}
			}
			else
			{
				return null;
			}
		}
		
		function loadEntities($ids, $entity_name, $entity_extension = null, $connection = null)
		{
			if ($connection == null)
			{
				$connection = $this->connection;
			}
			
			if ($entity_extension == null)
			{
				$entity_extension = $this->puzzle->PEM->current_extension;
			}
			
			$obj = $this->puzzle->PDM->createModel($entity_name, $entity_extension);
			$obj->defineContainer("mysql");
			
			// Create comma separated values of array
			
			$keys = implode($ids, ",");
			
			$connection->select($obj->_mysql->table, '*', $obj->_mysql->key . " in (" . $keys . ")");
			$temp = $connection->result;
			
			$ds = new PDataset();
			
			if ($temp != null)
			{
				for ($i = 0; $i < count($temp) ; $i++)
				{
					$obj = $this->puzzle->PDM->createModel($entity_name, $entity_extension);
					$obj->defineContainer("mysql");
					
					$rfields = $temp[$i];
					
					for($j = 0; $j < count($obj->_model->fields); $j++)
					{
						$field_name = $obj->_model->fields[$j];
						$field_mapping = $obj->_mysql->mapping[$field_name];
						
						if ($field_mapping == null or $field_mapping == "")
						{
							// If the object has the "Load Not Mapped Fields" as true...
							if ($obj->_mysql->lnmf)
							{
								$field_mapping = $field_name;
							}
						}
						
						if ($field_mapping != null && $field_mapping != "")
						{
							$obj->$field_name = $rfields[$field_mapping];
						}
					}
					
					$ds->addElement($obj);
				}
			}
			
			return $ds;
		}
		
		function saveEntity(&$entity, $connection = null)
		{
			if ($connection == null)
			{
				$connection = $this->connection;
			}
			
			$result = false;
			$idfield = $entity->_model->id;					// The id of the model
			$keyfield = $entity->_mysql->key;				// The key in the db
			
			if ($entity->$idfield == null || $entity->$idfield == "")
			{
				$noid = true;
			}
			
			if (!$noid)
			{
				$old = $this->loadEntity($entity->$idfield, $entity->model_name, $entity->model_extension, $connection);
				
				$insert_array = array();
				$update_array = array();
				
				for($i = 0; $i < count($entity->_model->fields); $i++)
				{
					$field_name = $entity->_model->fields[$i];
					
					$insert_array[] = $entity->$field_name;
					if ($field_name != $idfield)
						$update_array[$entity->_mysql->mapping[$field_name]] = $entity->$field_name;
				}
				
				if ($old != null)
				{
					$result = $connection->update($entity->_mysql->table, $update_array, array($entity->_mysql->key, $entity->$idfield));
				}
				else
				{
					$result = $connection->insert($entity->_mysql->table, $insert_array);
				}
			}
			else
			{
				$insert_array = array();
				$rows = $entity->_mysql->mapping;
				
				$rows = array_diff($rows, array($idfield));
				$rows = array_values($rows);
				$rows_string = implode(", ", $rows);
				
				for($i = 0; $i < count($rows); $i++)
				{
					$field_mapping = $rows[$i];
					$field_name = array_keys($entity->_mysql->mapping, $field_mapping);
					$insert_array[] = $entity->$field_name;
				}
				
				$result = $connection->insert($entity->table, $insert_array, $rows_string);
				$entity->$idfield = $connection->getLastID();
			}
			
			return $result;
		}
		
		function listEntity($entity_name, $entity_extension = null, $filter = null, $order = null, $connection = null)
		{
			if ($connection == null)
			{
				$connection = $this->connection;
			}
			
			if ($entity_extension == null)
			{
				$entity_extension = $this->puzzle->PEM->current_extension;
			}
			
			$obj = $this->puzzle->PDM->createModel($entity_name, $entity_extension);
			$obj->defineContainer("mysql");
			
			$connection->select($obj->_mysql->table, '*', $filter, $order);
			
			$temp = $connection->result;
			
			$ds = new PDataset();
			
			if ($temp != null)
			{
				for ($i = 0; $i < count($temp) ; $i++)
				{
					$obj = $this->puzzle->PDM->createModel($entity_name, $entity_extension);
					$obj->defineContainer("mysql");
					
					$rfields = $temp[$i];
					
					for($j = 0; $j < count($obj->_model->fields); $j++)
					{
						$field_name = $obj->_model->fields[$j];
						$field_mapping = $obj->_mysql->mapping[$field_name];
						
						if ($field_mapping == null or $field_mapping == "")
						{
							// If the object has the "Load Not Mapped Fields" as true...
							if ($obj->_mysql->lnmf)
							{
								$field_mapping = $field_name;
							}
						}
						
						if ($field_mapping != null && $field_mapping != "")
						{
							$obj->$field_name = $rfields[$field_mapping];
						}
					}		
					$ds->addElement($obj);
				}
			}
			
			return $ds;
		}
		
		
		// returns an array with an array for every result i.e ---> r[]['id'] = 5;
		function query($query)
		{
			$r = "";
			$query = $this->connection->executeQuery($query);
			
			if($query)
			{
			    $this->connection->result = array();
			    $this->connection->numResults = mysql_num_rows($query);
			    for($i = 0; $i < $this->connection->numResults; $i++)
			    {
				$r = mysql_fetch_array($query);
				$key = array_keys($r);
				for($x = 0; $x < count($key); $x++)
				{
				    // Sanitizes keys so only alphavalues are allowed
				    if(!is_int($key[$x]))
				    {
					if(mysql_num_rows($query) > 1)
					    $this->connection->result[$i][$key[$x]] = $r[$key[$x]];
					else if(mysql_num_rows($query) < 1)
					    $this->connection->result = null;
					else
					    $this->connection->result[0][$key[$x]] = $r[$key[$x]];
				    }
				}
			    }
			    return true;
			}
			else
			{
			    return false;
			}
			
			//$r = $this->connection->result;
			
			//return $r;
		}
		
		function executeSQL($file)
		{
			$stream = fopen($file, "r");
			$query = "";
			
			if ($stream)
			{
				while (($buffer = fgets($stream, 4096)) !== false)
				{
					//echo "Linea leida: $buffer <br/>";
					
					if (strpos($buffer, ";") !== false)
					{
						//$til = strstr($buffer, ";", true);
						$til = strstrb($buffer, ";");
						$query .= $til . ";";
						
						$query = str_replace("%%tp%%", $this->puzzle->config['db_prefix'], $query);
						$query = str_replace("%%db%%", $this->connection->dbname, $query);
						
						//echo "LA QUERY: $query <br/>";
						$this->connection->executeQuery($query);
						$query = "";
					}
					else
					{
						$query = $query . $buffer;
					} 
				}
				
				if (!feof($stream))
				{
					echo "Error: fallo inesperado de fgets()\n";
				}
				
				fclose($stream);
			}
		}
	}
	
?>
